package com.bill99.service.impl;

import com.bill99.http.util.HttpClient;
import com.bill99.mapper.mapper1.WorkOrdersInfoMapper;
import com.bill99.mapper.mapper2.CalculateDelayHourMapper;
import com.bill99.model.TableauProperties;
import com.bill99.service.IpoTrackerWorkOrderDelayService;
import com.bill99.util.DateUtil;
import com.bill99.util.JsonUtil;
import com.bill99.util.excel.ExcelWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Transactional
@Service(value = "ipoTrackerWorkOrderDelayServiceImpl")
public class IpoTrackerWorkOrderDelayServiceImpl implements IpoTrackerWorkOrderDelayService {
    @Autowired
    private CalculateDelayHourMapper tableauReportDelayHourDao;
    @Autowired
    private WorkOrdersInfoMapper workOrdersInfoDao;


    @Override
    public void pullData(Map<String, Object> map){

        try {
            //先清空表数据
            tableauReportDelayHourDao.deleteData();

            //最近6个月未关闭的工单数据

            List<Map<String, Object>> notClosedWbs = workOrdersInfoDao.getWorkOrdersInfo(map);
            tableauReportDelayHourDao.batchInsertDelayRecord(notClosedWbs);
        } catch (Exception e) {
           throw new RuntimeException("pullData Exception"+e.toString());
        }

    }

    @Override
    public void slaRelation(){
        try {
            List<Map<String, Object>> slaList = tableauReportDelayHourDao.slaList();

            for (Map<String, Object> salExtMap : slaList) {
                if (salExtMap.get("sla") != null && !"".equals(salExtMap.get("sla").toString())) {
                    tableauReportDelayHourDao.updateOneDelayRecord(salExtMap);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("pullData Exception"+e.toString());
        }

    }

    /***
     * describe: SLA为T+0的工单
     * creat_time: 2018/7/22 13:18
     * param: []
     * return: void
     */
    @Override
    public void slaTplusZero(){

        try {
            List<Map<String, Object>> slaPlusZeros = tableauReportDelayHourDao.slaPlusZero();
            for (Map<String, Object> slaPlusZero : slaPlusZeros) {
                Date createTime = (Date) slaPlusZero.get("createTime");

                //明天Date
                Date tomorrowDate = getTomorrowDate(createTime);

                //格式为yyyy-MM-dd的明天Date
                Date tomDate = DateUtil.parse("yyyy-MM-dd", DateUtil.formatDateTime("yyyy-MM-dd", tomorrowDate));
                Date tomSevenTeen = toSecondDate(tomDate, " 17:00:00");
                Map<String, Object> tradeMap = new HashMap<String, Object>();
                tradeMap.put("wordDate", tomDate);

                //时间格式化成年月日
                String todayStr = new SimpleDateFormat("yyyy-MM-dd").format(createTime);
                Date todayDate = DateUtil.parse("yyyy-MM-dd", todayStr);

                //第二个工单超时点 下个工作日第一天的17:00
                Map<String, Object> todayMap = new HashMap<String, Object>();
                todayMap.put("anyDay", todayDate);
                Map<String, Object> nextWorkDay = tableauReportDelayHourDao.nextWorkDay(todayMap);
                Date workDate = (Date) nextWorkDay.get("workDate");
                Date twoDelayTime = toSecondDate(workDate, " 17:00:00");

                //compare point
                Date comparePoint = toSecondDate(toDayDate(createTime), " 17:00:00");
                //第一个工单超时点 当天24:00 也就是第二天的00:00
                Date oneDelayTime = toSecondDate(toDayDate(tomorrowDate), " 00:00:00");

                if (!this.isTradeDay(tradeMap)) {
                    //工单创建时间的tomorrow是节假日
                    Map<String, Object> result = new HashMap<String, Object>();
                    result.put("id", slaPlusZero.get("id"));
                    if (compare(comparePoint, createTime)) {
                        //节假日前最后一天工作の的00:00:00<=创建时间<节假日前最后一天工作日の17:00:00  规定关闭工单时间当天の24:00
                        putDelayHour(oneDelayTime, result);
                    }
                    if (compareEqual(createTime, comparePoint) && compare(oneDelayTime, createTime)) {
                        //节假日前最后一天工作日の17:00:00<=创建时间<节假日前最后一天工作日の24:00:00  规定关闭工单时间节假日后工作日第一天の17:00
                        putDelayHour(twoDelayTime, result);
                    }
                    tableauReportDelayHourDao.updateOneDelayRecord(result);
                }
                Map<String, Object> twoTrade = new HashMap<String, Object>();
                twoTrade.put("wordDate", todayDate);

                if (!this.isTradeDay(twoTrade)) {
                    //创单时间是在节假日
                    Map<String, Object> result = new HashMap<String, Object>();
                    result.put("id", slaPlusZero.get("id"));
                    putDelayHour(twoDelayTime, result);
                    tableauReportDelayHourDao.updateOneDelayRecord(result);
                }

                if (this.isTradeDay(tradeMap) && this.isTradeDay(twoTrade)) {
                    //创单时间是交易日但是创单时间的明天不是节假日
                    Map<String, Object> result = new HashMap<String, Object>();
                    result.put("id", slaPlusZero.get("id"));
                    if (compare(comparePoint, createTime)) {
                        putDelayHour(oneDelayTime, result);
                    } else {
                        putDelayHour(tomSevenTeen, result);
                    }
                    tableauReportDelayHourDao.updateOneDelayRecord(result);
                }

            }
        } catch (Exception e) {
            throw new RuntimeException("pullData Exception"+e.toString());
        }
    }

    @Override
    public void slaNotTplusZero(){
        try {
            List<Map<String, Object>> slaPlusZeros = tableauReportDelayHourDao.slaNotPlusZero();

            for (Map<String, Object> slaPlusZero : slaPlusZeros) {
                Map<String, Object> result = new HashMap<String, Object>();
                result.put("id", slaPlusZero.get("id"));
                Date createTime = (Date) slaPlusZero.get("createTime");
                Integer slaHours = (Integer) slaPlusZero.get("slaHours");
                Date delayPointDate = anyHourLater(createTime, slaHours);
                //不超时delayHour为0.00
                BigDecimal delayHour = new BigDecimal("0.00");
                if (compare(new Date(), delayPointDate)) {
                    //大于规定时间算超时
                    DecimalFormat df = new DecimalFormat("0.00");//格式化小数
                    float hour = (float) (new Date().getTime() - delayPointDate.getTime()) / 3600000;
                    String num = df.format(hour);//返回的是String类型
                    delayHour = new BigDecimal(num);
                }
                result.put("delayHour", delayHour);
                result.put("delayTimestamp", delayPointDate);
                tableauReportDelayHourDao.updateOneDelayRecord(result);
            }
        } catch (Exception e) {
            throw new RuntimeException("pullData Exception"+e.toString());
        }
    }

    @Override
    public String generateExcel(String templatefileName,String filepath){
        //查询
        String today="";
        try {
            Map<String,Object> nodelay=new HashMap();
            nodelay.put("nodelay",new BigDecimal("0.00"));
            List<Map<String, Object>> emailDatalist = tableauReportDelayHourDao.emailDatalist(nodelay);
//            List<Map<String,Object>> emailDatalist=new ArrayList();
//
//            for(int i=0;i<=23;i++){
//                Map<String,Object> map=new HashMap();
//                String day = DateUtil.formatDateTime("yyyy-MM-dd", new Date());
//                if(i<=9){
//                    day = day + " 0" + i;
//                    map.put("column2","汉字");
//                }else{
//                    day=day+" "+day;
//                    map.put("column2",new BigDecimal("41912790.62"));
//                }
//                map.put("column1",day);
//                map.put("column3",new BigDecimal("575777611.9"));
//                map.put("column4",12345);
//                map.put("column5",new BigDecimal("575777611.90"));
//                map.put("column6",0);
//
//            }
            ExcelWriter cpsExcelWrite=new ExcelWriter();
            cpsExcelWrite.setVxlsFile(templatefileName);
            cpsExcelWrite.setXlsVersion("2007");
            today=DateUtil.formatDateTime("yyyyMMddHHmmss",new Date());
            File file = new File(filepath+today+"/", today+".xlsx");
            if (!file.exists()) {
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                file.createNewFile();
            }
            cpsExcelWrite.writeToExcel(emailDatalist, new FileOutputStream(file));


        } catch (Exception e) {
            throw new RuntimeException("generateExcel | Exception",e);
        }

        return today+"/"+today+".xlsx";
    }

    @Override
    public void generatePic(TableauProperties tableau)throws Exception{

        Map<String, Object> params = new HashMap<String, Object>();

        Map<String, Object> param = new HashMap<String, Object>();
//
        param.put("name", tableau.getName());
        param.put("password", tableau.getPassword());
        Map<String, String> uri = new HashMap<String, String>();
        uri.put("contentUrl", tableau.getContentUrl());
        param.put("site", uri);

        params.put("credentials", param);
        String result = jsonPost(tableau.getUrl(), params);
        Map<String, Object> jsonMap = JsonUtil.convert2Object(result, new HashMap<String, Object>());
//		//发送post请求获取项目列表
        Map<String, Object> creMap = (Map<String, Object>) jsonMap.get("credentials");
        Map<String, Object> siteMap = (Map<String, Object>) creMap.get("site");
        String siteID = (String) siteMap.get("id");
        String token = (String) creMap.get("token");
        String urlck = "https://tableau.99bill.net/api/2.8/sites/" + siteID + "/views/"+tableau.getViewId()+"/image";
//		//发送get请求
        HttpClient client = new HttpClient();
        client.getPic(urlck, token,tableau.getUploadPath());
    }


    /**
     * 发送HttpPost请求
     *
     * @param strURL 服务地址
     * @param params
     * @return 成功:返回json字符串<br/>
     */
    public static String jsonPost(String strURL, Map<String, Object> params) {
        try {
            URL url = new URL(strURL);// 创建连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod("POST"); // 设置请求方式
            connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
            connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
            connection.connect();
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8编码
            out.append(JsonUtil.convert2Json(params));
            out.flush();
            out.close();

            int code = connection.getResponseCode();
            InputStream is = null;
            if (code == 200) {
                is = connection.getInputStream();
            } else {
                is = connection.getErrorStream();
            }

            // 读取响应
            int length = (int) connection.getContentLength();// 获取长度
            if (length != -1) {
                byte[] data = new byte[length];
                byte[] temp = new byte[512];
                int readLen = 0;
                int destPos = 0;
                while ((readLen = is.read(temp)) > 0) {
                    System.arraycopy(temp, 0, data, destPos, readLen);
                    destPos += readLen;
                }
                String result = new String(data, "UTF-8"); // utf-8编码
                return result;
            }

        } catch (IOException e) {
//            LOG.error("Exception occur when send http post request!", e);
        }
        return "error"; // 自定义错误信息
    }


    private void putDelayHour(Date todayTillDate, Map<String, Object> result) {
        DecimalFormat df = new DecimalFormat("0.00");//格式化小数
        float hour = (float) (new Date().getTime() - todayTillDate.getTime()) / 3600000;
        String num = df.format(hour);//返回的是String类型
        BigDecimal delayHour = new BigDecimal(num);
        result.put("delayHour", delayHour);
        result.put("delayTimestamp", todayTillDate);
    }

    private Date getTomorrowDate(Date createTime) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(createTime);
        cal.add(Calendar.DATE, +1);
        return cal.getTime();
    }


    @Override
    public Boolean isTradeDay(Map date){
        Map<String, Object> tradeDay = tableauReportDelayHourDao.isTradeDay(date);
        Boolean flag = false;
        if (tradeDay != null && !tradeDay.isEmpty()) {
            if ("是".equals(tradeDay.get("holidayFlag").toString())) {
                flag = true;
            }
        }
        return flag;
    }

    private Map<String, Object> prepare(Map<String, Object> notClosedWb) {


        Map<String, Object> record = new HashMap<String, Object>();

        if (notClosedWb.containsKey("CreateTime")) {
            record.put("createTime", notClosedWb.get("CreateTime"));
        }
        if (notClosedWb.containsKey("ProblemCode")) {
            record.put("problemCode", notClosedWb.get("ProblemCode"));
        }
        if (notClosedWb.containsKey("ProjectName")) {
            record.put("projectName", notClosedWb.get("ProjectName"));
        }
        if (notClosedWb.containsKey("Select1")) {
            record.put("workOrderType", notClosedWb.get("Select1"));
        }
        if (notClosedWb.containsKey("AssignedToUserName")) {
            record.put("assignedToUserName", notClosedWb.get("AssignedToUserName"));
        }
        return record;
    }

    private Boolean compare(Date one, Date two) {
        if (one == null || two == null) {
            return false;
        } else {
            return one.getTime() > two.getTime();

        }
    }

    private Boolean compareEqual(Date one, Date two) {
        if (one == null || two == null) {
            return false;
        } else {
            return one.getTime() >= two.getTime();

        }
    }

    private Date toSecondDate(Date yyyyMMdd, String hhmmss) {
        String yymmdd = DateUtil.formatDateTime("yyyy-MM-dd", yyyyMMdd);
        return DateUtil.parse("yyyy-MM-dd HH:mm:ss", yymmdd + hhmmss);
    }

    private Date toDayDate(Date yyyyMMddHHmmss) {
        String date = DateUtil.formatDateTime("yyyy-MM-dd HH:mm:ss", yyyyMMddHHmmss);
        return DateUtil.parse("yyyy-MM-dd", date);
    }

    private Date anyHourLater(Date date, Integer hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hours);
        return calendar.getTime();
    }




}
